﻿using System;
using System.Collections;
using System.Collections.Generic;

namespace Priority_Queue
{
	// Token: 0x0200032C RID: 812
	public class SimplePriorityQueue<TItem, TPriority> : IPriorityQueue<TItem, TPriority>, IEnumerable<TItem>, IEnumerable where TPriority : IComparable<TPriority>
	{
		// Token: 0x060014F2 RID: 5362 RVA: 0x00088C4C File Offset: 0x00086E4C
		public SimplePriorityQueue()
		{
			this._queue = new GenericPriorityQueue<SimplePriorityQueue<TItem, TPriority>.SimpleNode, TPriority>(10);
		}

		// Token: 0x060014F3 RID: 5363 RVA: 0x00088C64 File Offset: 0x00086E64
		private SimplePriorityQueue<TItem, TPriority>.SimpleNode GetExistingNode(TItem item)
		{
			EqualityComparer<TItem> @default = EqualityComparer<TItem>.Default;
			foreach (SimplePriorityQueue<TItem, TPriority>.SimpleNode simpleNode in this._queue)
			{
				if (@default.Equals(simpleNode.Data, item))
				{
					return simpleNode;
				}
			}
			throw new InvalidOperationException("Item cannot be found in queue: " + item);
		}

		// Token: 0x17000353 RID: 851
		// (get) Token: 0x060014F4 RID: 5364 RVA: 0x00088CEC File Offset: 0x00086EEC
		public int Count
		{
			get
			{
				object queue = this._queue;
				int count;
				lock (queue)
				{
					count = this._queue.Count;
				}
				return count;
			}
		}

		// Token: 0x17000354 RID: 852
		// (get) Token: 0x060014F5 RID: 5365 RVA: 0x00088D30 File Offset: 0x00086F30
		public TItem First
		{
			get
			{
				object queue = this._queue;
				TItem result;
				lock (queue)
				{
					if (this._queue.Count <= 0)
					{
						throw new InvalidOperationException("Cannot call .First on an empty queue");
					}
					SimplePriorityQueue<TItem, TPriority>.SimpleNode first = this._queue.First;
					result = ((first == null) ? default(TItem) : first.Data);
				}
				return result;
			}
		}

		// Token: 0x060014F6 RID: 5366 RVA: 0x00088DAC File Offset: 0x00086FAC
		public void Clear()
		{
			object queue = this._queue;
			lock (queue)
			{
				this._queue.Clear();
			}
		}

		// Token: 0x060014F7 RID: 5367 RVA: 0x00088DF0 File Offset: 0x00086FF0
		public bool Contains(TItem item)
		{
			object queue = this._queue;
			bool result;
			lock (queue)
			{
				EqualityComparer<TItem> @default = EqualityComparer<TItem>.Default;
				foreach (SimplePriorityQueue<TItem, TPriority>.SimpleNode simpleNode in this._queue)
				{
					if (@default.Equals(simpleNode.Data, item))
					{
						return true;
					}
				}
				result = false;
			}
			return result;
		}

		// Token: 0x060014F8 RID: 5368 RVA: 0x00088E8C File Offset: 0x0008708C
		public TItem Dequeue()
		{
			object queue = this._queue;
			TItem data;
			lock (queue)
			{
				if (this._queue.Count <= 0)
				{
					throw new InvalidOperationException("Cannot call Dequeue() on an empty queue");
				}
				SimplePriorityQueue<TItem, TPriority>.SimpleNode simpleNode = this._queue.Dequeue();
				data = simpleNode.Data;
			}
			return data;
		}

		// Token: 0x060014F9 RID: 5369 RVA: 0x00088EF4 File Offset: 0x000870F4
		public void Enqueue(TItem item, TPriority priority)
		{
			object queue = this._queue;
			lock (queue)
			{
				SimplePriorityQueue<TItem, TPriority>.SimpleNode node = new SimplePriorityQueue<TItem, TPriority>.SimpleNode(item);
				if (this._queue.Count == this._queue.MaxSize)
				{
					this._queue.Resize(this._queue.MaxSize * 2 + 1);
				}
				this._queue.Enqueue(node, priority);
			}
		}

		// Token: 0x060014FA RID: 5370 RVA: 0x00088F74 File Offset: 0x00087174
		public void Remove(TItem item)
		{
			object queue = this._queue;
			lock (queue)
			{
				try
				{
					this._queue.Remove(this.GetExistingNode(item));
				}
				catch (InvalidOperationException innerException)
				{
					throw new InvalidOperationException("Cannot call Remove() on a node which is not enqueued: " + item, innerException);
				}
			}
		}

		// Token: 0x060014FB RID: 5371 RVA: 0x00088FE8 File Offset: 0x000871E8
		public void UpdatePriority(TItem item, TPriority priority)
		{
			object queue = this._queue;
			lock (queue)
			{
				try
				{
					SimplePriorityQueue<TItem, TPriority>.SimpleNode existingNode = this.GetExistingNode(item);
					this._queue.UpdatePriority(existingNode, priority);
				}
				catch (InvalidOperationException innerException)
				{
					throw new InvalidOperationException("Cannot call UpdatePriority() on a node which is not enqueued: " + item, innerException);
				}
			}
		}

		// Token: 0x060014FC RID: 5372 RVA: 0x0008905C File Offset: 0x0008725C
		public IEnumerator<TItem> GetEnumerator()
		{
			List<TItem> list = new List<TItem>();
			object queue = this._queue;
			lock (queue)
			{
				foreach (SimplePriorityQueue<TItem, TPriority>.SimpleNode simpleNode in this._queue)
				{
					list.Add(simpleNode.Data);
				}
			}
			return list.GetEnumerator();
		}

		// Token: 0x060014FD RID: 5373 RVA: 0x000890F0 File Offset: 0x000872F0
		IEnumerator IEnumerable.GetEnumerator()
		{
			return this.GetEnumerator();
		}

		// Token: 0x060014FE RID: 5374 RVA: 0x000890F8 File Offset: 0x000872F8
		public bool IsValidQueue()
		{
			object queue = this._queue;
			bool result;
			lock (queue)
			{
				result = this._queue.IsValidQueue();
			}
			return result;
		}

		// Token: 0x040017BD RID: 6077
		private const int INITIAL_QUEUE_SIZE = 10;

		// Token: 0x040017BE RID: 6078
		private readonly GenericPriorityQueue<SimplePriorityQueue<TItem, TPriority>.SimpleNode, TPriority> _queue;

		// Token: 0x0200032D RID: 813
		private class SimpleNode : GenericPriorityQueueNode<TPriority>
		{
			// Token: 0x060014FF RID: 5375 RVA: 0x0008913C File Offset: 0x0008733C
			public SimpleNode(TItem data)
			{
				this.Data = data;
			}

			// Token: 0x17000355 RID: 853
			// (get) Token: 0x06001500 RID: 5376 RVA: 0x0008914B File Offset: 0x0008734B
			// (set) Token: 0x06001501 RID: 5377 RVA: 0x00089153 File Offset: 0x00087353
			public TItem Data { get; private set; }
		}
	}
}
